package com.campus.merchant.service;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.campus.merchant.entity.Goods;
import com.campus.merchant.entity.GoodsSpecGroup;
import com.campus.merchant.entity.GoodsSpecOption;
import com.campus.merchant.mapper.GoodsMapper;
import com.campus.merchant.mapper.GoodsSpecGroupMapper;
import com.campus.merchant.mapper.GoodsSpecOptionMapper;
import com.campus.merchant.vo.goods.GoodsVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * <p>
 * 商品表 服务实现类
 * </p>
 *
 * @author ZhaoYuJie
 * @since 2025-04-18
 */
@Service
public class GoodsService extends ServiceImpl<GoodsMapper, Goods> {
    @Autowired
    private GoodsSpecGroupMapper goodsSpecGroupMapper;
    @Autowired
    private GoodsSpecOptionMapper goodsSpecOptionMapper;


    /**
     * 保存商品及规格组、规格选项
     */
    @Transactional(rollbackFor = Exception.class)
    public void saveGoodsWithSpecs(Goods goods, String specJson) {
        save(goods);
        saveOrUpdateSpecs(goods.getId(), specJson);
    }

    /**
     * 编辑商品及规格组、规格选项
     */
    @Transactional(rollbackFor = Exception.class)
    public void updateGoodsWithSpecs(Goods goods, String specJson) {
        updateById(goods);
        saveOrUpdateSpecs(goods.getId(), specJson);
    }

    /**
     * 解析specJson并保存规格组和选项
     */
    private void saveOrUpdateSpecs(Integer goodsId, String specJson) {
        // 删除原有规格组和选项
        List<GoodsSpecGroup> oldGroups = goodsSpecGroupMapper.selectList(new LambdaQueryWrapper<GoodsSpecGroup>().eq(GoodsSpecGroup::getGoodsId, goodsId));
        if (!oldGroups.isEmpty()) {
            List<Integer> groupIds = new ArrayList<>();
            for (GoodsSpecGroup group : oldGroups) {
                groupIds.add(group.getId());
            }
            goodsSpecOptionMapper.delete(new LambdaQueryWrapper<GoodsSpecOption>().in(GoodsSpecOption::getSpecGroupId, groupIds));
            goodsSpecGroupMapper.delete(new LambdaQueryWrapper<GoodsSpecGroup>().eq(GoodsSpecGroup::getGoodsId, goodsId));
        }
        if (specJson == null || specJson.isEmpty()) {
            return;
        }
        try {
            List<SpecGroupDTO> groupDTOList = JSONUtil.toList(JSONUtil.parseArray(specJson), SpecGroupDTO.class);
            for (SpecGroupDTO groupDTO : groupDTOList) {
                GoodsSpecGroup group = new GoodsSpecGroup();
                group.setGoodsId(goodsId);
                group.setName(groupDTO.getName());
                group.setCreateTime(LocalDateTime.now());
                group.setUpdateTime(LocalDateTime.now());
                goodsSpecGroupMapper.insert(group);
                if (groupDTO.getOptions() != null) {
                    for (SpecOptionDTO optionDTO : groupDTO.getOptions()) {
                        GoodsSpecOption option = new GoodsSpecOption();
                        option.setSpecGroupId(group.getId());
                        option.setName(optionDTO.getName());
                        option.setPrice(optionDTO.getPrice() == null ? BigDecimal.ZERO : optionDTO.getPrice());
                        option.setCreateTime(LocalDateTime.now());
                        option.setUpdateTime(LocalDateTime.now());
                        goodsSpecOptionMapper.insert(option);
                    }
                }
            }
        } catch (Exception e) {
            throw new RuntimeException("规格JSON解析失败", e);
        }
    }

    // DTO内部类
    private static class SpecGroupDTO {
        private String name;
        private List<SpecOptionDTO> options;
        public String getName() { return name; }
        public void setName(String name) { this.name = name; }
        public List<SpecOptionDTO> getOptions() { return options; }
        public void setOptions(List<SpecOptionDTO> options) { this.options = options; }
    }
    private static class SpecOptionDTO {
        private String name;
        private BigDecimal price;
        public String getName() { return name; }
        public void setName(String name) { this.name = name; }
        public BigDecimal getPrice() { return price; }
        public void setPrice(BigDecimal price) { this.price = price; }
    }

    public List<GoodsVO> getGoodsList(Integer merchantId, Integer categoryId, Integer status) {
        LambdaQueryWrapper<Goods> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Goods::getMerchantId, merchantId);
        if (categoryId != null) {
            queryWrapper.eq(Goods::getCategoryId, categoryId);
        }
        if (status != null) {
            queryWrapper.eq(Goods::getStatus, status);
        }
        List<Goods> goodsList = list(queryWrapper);
        List<GoodsVO> goodsVOList = BeanUtil.copyToList(goodsList, GoodsVO.class);
        for (GoodsVO goodsVO : goodsVOList) {
            goodsVO.setSpecJson(getGoodsSpecJson(goodsVO.getId()));
        }
        return goodsVOList;
    }

    public void batchUpdateStatus(List<Integer> ids, Integer status) {
        LambdaUpdateWrapper<Goods> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.in(Goods::getId, ids)
                     .set(Goods::getStatus, status)
                     .set(Goods::getUpdateTime, LocalDateTime.now());
        update(updateWrapper);
    }

    public void batchDelete(List<Integer> ids) {
        removeByIds(ids);
    }

    public String getGoodsSpecJson(Integer goodsId) {
        List<GoodsSpecGroup> groups = goodsSpecGroupMapper.selectList(
            new LambdaQueryWrapper<GoodsSpecGroup>().eq(GoodsSpecGroup::getGoodsId, goodsId));
        
        List<Map<String, Object>> result = new ArrayList<>();
        for (GoodsSpecGroup group : groups) {
            Map<String, Object> groupMap = new HashMap<>();
            groupMap.put("name", group.getName());
            
            List<GoodsSpecOption> options = goodsSpecOptionMapper.selectList(
                new LambdaQueryWrapper<GoodsSpecOption>().eq(GoodsSpecOption::getSpecGroupId, group.getId()));
            
            List<Map<String, Object>> optionList = new ArrayList<>();
            for (GoodsSpecOption option : options) {
                Map<String, Object> optionMap = new HashMap<>();
                optionMap.put("name", option.getName());
                optionMap.put("price", option.getPrice());
                optionList.add(optionMap);
            }
            
            groupMap.put("options", optionList);
            result.add(groupMap);
        }
        return JSONUtil.toJsonStr(result);
    }
}
